<?php


namespace app\model;


/**
 *
 *
 * @mixin \think\Model
 * @property int $id
 * @property int $supplier_id 供应商id
 * @property int $supplier_discount 供应商结算折扣（%）
 * @property int $supplier_price 供应商结算价。单位：分
 * @property int $settle_price 代理商结算价。单位：分
 * @property int $profit 代理商利润。单位：分
 * @property int $agent_id 代理商id
 * @property bool $settle_type 代理商结算类型
 * @property int $settle_discount 结算折扣
 * @property int $platform_profit 平台利润。单位：分
 * @property string $order_id 平台订单号
 * @property string $out_order_id 第三方订单信息
 * @property int $origin_amount 原价，单位分
 * @property int $amount 实际价格，单位分
 * @property int $pay_amount 实际支付金额 如果没有优惠抵扣的话=price
 * @property bool $pay_type 支付方式
 * @property bool $pay_status 支付状态 0 未支付 1 已支付
 * @property string $pay_time 支付时间
 * @property bool $refund_status 退款状态 1未退款 2退款中 3已退款
 * @property int $refund_amount 退金额 如果是已退款 并且金额小于pay_amount表示部分退款
 * @property int $user_id 支付用户id
 * @property int $cnid 渠道id
 * @property bool $serv_type 订单业务类型。不同我业务不同取值。type则是在业务下订单类型的区分
 * @property bool $type 订单类型。业务下订单子类型。比如权益订单，不同权益可能需要不同类型标识
 * @property string $settled_at 结算时间
 * @property string $created_at 创建时间
 * @property string $updated_at 更新时间
 * @property string $deleted_at
 * @property int $status 0未提交 1已提交  2提交失败 3充值成功  4充值失败 5订单处理中 10超时关闭
 * @property string $status_msg 状态信息
 * @property string $complete_at 完成时间
 * @property string $supplier_order_sn 供应商返回的订单号
 * @property bool $agent_settle_status 结算状态  1无需结算 2待结算 3已结算
 * @property string $card_info 卡密信息
 * @property-read \app\model\BaseSupplier $supplier
 * @property-read \app\model\Agent $agent
 * @property-read \app\model\GoodsCart $goods_cart
 * @property string $account 充值账号
 * @property string $product_name 产品名称
 * @property string $product_image 产品图片
 * @property string $log 订单日志
 * @property string $supplier_code 供应商代号
 * @property int $salesman_id 业务员
 * @property string $order_created_at 订单创建时间（可能第三方）
 * @property-read string $order_status_text
 * @property-read array $return_status
 * @property mixed $ext_data 扩展信息
 * @property string $title 标题
 * @property string $agent_name 代理商名称
 * @property string $serv_type_name 服务名称
 * @property-read string $agent_company_name
 * @method static \think\db\Query agentId()
 * @property string $curl_date 订单请求第三方更新的时间
 * @property-read \app\model\AgentChannel $agent_channel
 * @property string $sid 自定义标记信息
 * @property-read \app\model\CouponOrderSid $coupon_order_sid
 * @property-read \app\model\MobileUser $user
 * @property string $remark 备注
 * @property float $MARK 折扣标识
 * @property-read mixed $openid
 * @property-read mixed $item_status
 * @property string $mobile 手机号
 * @property int $quote_id 关联表字段
 * @property-read bool|int $expired_time
 * @property-read \app\model\CouponProductChannel $coupon_product_channel
 * @property int $supplier_status 1 未提交 2 待提交 4 已提交 6 成功 8 失败 99 轮训
 * @property int $pay_log_id 支付id
 * @property-read \app\model\PayLog $pay_log
 * @property-read mixed $pay_type_name
 * @property-read \app\model\MovieOrder $movieOrder
 * @property-read \app\model\MovieOrder $movie_order
 * @property-read mixed $detail_url
 * @property-read mixed $user_share_openid
 * @method static \think\db\Query estimate() //预估收入查询
 * @method static \think\db\Query exceptSettleEstimate() //未结算
 * @property-read \app\model\ServiceSub $service_sub
 * @property int $template_id 模板id 冗余字段，插入时自动完成
 * @property-read mixed $open_order_sn
 * @property int $new_supplier_price 价格降低时候，供应商结算价。单位：分
 * @property string $create_order_from 下单来源 h5 applet 小程序
 * @property string $test_at
 * @property int $brand_id 品牌id
 * @property int $product_id 产品id
 * @property string $order_finish_at 订单完成时间（第三方结算）
 * @property-read \app\model\CouponBrand $coupon_brand
 * @property-read mixed $settle_status_name
 * @property int $extension_type 推广类型用于我的推广统计标记
 */

use app\agent\model\Channel;
use app\common\facade\auth\Auth;
use app\common\model\Export;
use app\common\service\around\JtkAroundService;
use app\common\service\auth\AuthApiService;
use app\common\service\auth\AuthOpenService;
use app\common\service\auth\AuthYmshService;
use app\common\service\order\order_status\OrderStatusService;
use app\common\service\order\pipeline\coupon\ProductInfo;
use app\common\service\order\pipeline\coupon\RequestValidate;
use app\common\service\stat\StatService;
use app\job\CouponOrderUpdateJob;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use think\db\Query;
use think\Exception;
use think\facade\Log;
use think\Model;
use think\Pipeline;

class CouponOrder extends CouponOrderOld
{

    protected $table = 'coupon_order';


    public static $withSearch = [
        'tab_status',
        'created_date',
        'bar_field',
        'supplier_name',
        'agent_name',
        'order_id',
        'complete_at',
        'merchant_id',
        'app_id',
        'supplier_name',
        'settle_type',
        'channel_id',
        'pay_time',
        'start_at',
        'end_at',
        'channel_name',
        'agent_id',
        'finance_status',
        'serv_type',
        'product_name',
        'template_id',
        'account',
        'create_order_from',
        'search_type',//统计类型
        'brand_id',//品牌搜索
        'product_id',//单品搜索
        'title',//服务统计
        'cnid',//渠道统计
        'from',//搜搜统计
    ];

    // 定义全局的查询范围
    protected $globalScope = ['agentId'];

// 设置json类型字段
    protected $json = ['ext_data'];

    // 设置JSON数据返回数组
    protected $jsonAssoc = true;

    // status 订单状态 0未提交 1已提交  2提交失败 3充值成功  4充值失败 5订单处理中 10超时关闭
    const C_STATUS_NO_SUBMIT = 0;
    const C_STATUS_SUBMIT = 1;  //订单提交 进行中
    const C_STATUS_SUBMIT_FAIL = 2;  // 提交失败
    const C_STATUS_RECHARGE_SUCCESS = 3;  // 充值成功
    const C_STATUS_RECHARGE_FAIL = 4;  // 充值失败
    const C_STATUS_PROCESSING = 5;  // 订单处理中 比如核销中 已购买单未使用
    const C_STATUS_TIMEOUT_CLOSE = 10;  // 超时关闭

    // pay_status 支付状态  0 未支付 1 已支付
    const C_PAY_STATUS_NO = 0;  //  未支付
    const C_PAY_STATUS_YES = 1; // 已支付

    // refund_status 退款状态 1未退款 2退款中 3已退款
    const C_REFUND_STATUS_NO = 1; // 未退款
    const C_REFUND_STATUS_ING = 2; // 退款中
    const C_REFUND_STATUS_HAVE = 3; // 已退款

    const C_AGENT_SETTLE_STATUS_NO = 1;  // 无需结算
    const C_AGENT_SETTLE_STATUS_WAIT = 2; // 待结算
    const C_AGENT_SETTLE_STATUS_SUCCESS = 3;  // 已结算

    // 平台
    const C_PLATFORM_ADMIN = PLATFORM_ADMIN;  // 总后台
    const C_PLATFORM_AGENT = PLATFORM_AGENT;  // 代理商
    const C_PLATFORM_H5 = 'h5';  // h5

    //结算类型

    const C_SETTLE_TYPE = SETTLE_TYPE_PROFIT;//佣金结算
    const C_SETTLE_TYPE_AGENT_SELF = SETTLE_TYPE_AGENT_SELF;//佣金结算

    // 1 未提交 2 待提交 4 已提交 6 成功 8 失败 99 轮训
    const SUPPLIER_STATUS_NO = 1;  //未提交
    const SUPPLIER_STATUS_WAIT = 2;  //等待
    const SUPPLIER_STATUS_SUBMIT = 4; //提交
    const SUPPLIER_STATUS_SUCCESS = 6; //成功
    const SUPPLIER_STATUS_FAIL = 8; //失败
    const SUPPLIER_STATUS_REFUNDING = 9; // 提交申请退款 type = 10 自营才会用到
    const SUPPLIER_STATUS_ROTATION = 99; //轮训，查看是否存在其他可用的供应商
    const SUPPLIER_STATUS_WAIT_CONFIRM = 100; // 人工待确认 网络超时或者第三方未响应需要人工确认的  ps:聚推客在用


    const EXPIRED_TIME = 600;//秒  未支付订单过期时间 10分钟未支付


    const TYPE_COUPON_SELF_EMPLOYED = 10;//自营 走支付和退款 ps:权益、周边游

    const TYPE_MOBILE_CPS = 20;          //话费充值类型


    // 隐藏字段
    protected $hidden = ['log', 'supplier_code'];

    //搜索来自
    const SEARCH_FROM = 'extension';


    /*
     * 请求参数
     */
    public $params;


    public function __construct(array $data = [])
    {
        //开放平台显示的字段
        if (Auth::from() == FROM_OPEN_PLATFORM_API) {
            $this->visible = [
                'order_id',
                'amount',
                'order_created_at',
                'title',
                'product_name',
                'product_image',
                'serv_type',
                'profit',
                'settle_price',
                'pay_amount',
            ];
        }

        parent::__construct($data);
    }


//    public static function onAfterInsert(Model $model): void
//    {
//        queue(CouponOrderUpdateJob::class, $model);
//    }
//
//    public static function onAfterUpdate(Model $model): void
//    {
//        queue(CouponOrderUpdateJob::class, $model);
//    }

    /**
     * 供应商
     */
    public function supplier()
    {
        return $this->hasOne(BaseSupplier::class, 'id', 'supplier_id');
    }

    /**
     * 代理商
     */
    public function agent()
    {
        return $this->hasOne(Agent::class, 'id', 'agent_id');
    }

    /**
     * 服务名称
     */
    public function serviceSub()
    {
        return $this->hasOne(ServiceSub::class, 'serv_type', 'serv_type');
    }

    /**
     * 用户
     */
    public function user()
    {

        return $this->hasOne(MobileUser::class, 'id', 'user_id');

    }

    /**
     * 影票
     */
    public function movieOrder()
    {
        return $this->hasOne(MovieOrder::class, 'id', 'quote_id');
    }

    /**
     * 订单详情页
     * @param $value
     * @param $model
     */
    public function getDetailUrlAttr($value, $model)
    {
        if ($model['serv_type'] == PRODUCT_AROUND_SHOP_SERV && $model['type'] == self::TYPE_COUPON_SELF_EMPLOYED) {
            return env('app.api_url') . '/u/' . alphaID($this->id);
//            $orderList = $model['ext_data'][JtkAroundService::ORDER_NOTIFY_SEND]['orderList'] ?? [];
//            if ($orderList) {
//                $orderFirstInfo = Collect($orderList)->first();
//                $detailUrl = $orderFirstInfo['detailUrl'] ?? '';
//            }
//            return $detailUrl;
        }
        return env('app.api_url') . '/c/' . alphaID($this->id);
    }

    public function getUserShareOpenidAttr($value, $model)
    {
        return !empty($this->couponOrderSid) ? $this->couponOrderSid->user_share_openid : '';
    }

    /**
     * @param string $name
     */
    public function getOpenidAttr($value, $model)
    {
        return !empty($this->user) ? $this->user->openid : 0;
    }

    /**
     * @param $value
     * @param $model
     * @return false|int
     */
    public function getExpiredTimeAttr($value, $model)
    {
        $num = strtotime($this->created_at) + self::EXPIRED_TIME - time();
        if ($num < 0) {
            return 0;
        }
        return $num;
    }


    /**
     * 获取扩展字段
     */
    public function getExtDataAttr($value, $model)
    {
        //影票
        return $value;

        if ($this->serv_type != PRODUCT_FILM_SERV) {
            return $value;
        }

        if (is_string($value)) return $value;

        if (!is_array($value)) {
            $value = collect($value)->toArray();
        }

        /**
         * 都为空
         */
        if (empty($value['ticket_code']) && empty($value['ticket_image'])) {
            return $value;
        }


        try {

            if (!empty($value['ticket_code'])) {

                $arr = [];

                //如果二维码为空
                foreach ($value['ticket_code'] as $code) {
                    $arr[] = env('app.api_url') . '/qr?code=' . $code;
                }

                $value['ticket_image'] = $arr;

            }

        } catch (Exception $exception) {

            Log::info('处理扩展字段失败');
            Log::info($exception->getMessage() . $exception->getFile() . $exception->getLine());

        }

        return $value;


    }

    /**
     * 关联商品购物车
     * @return \think\model\relation\HasOne
     */
    public function goodsCart()
    {
        return $this->hasOne(GoodsCart::class, 'order_id');
    }

    public function couponProductChannel()
    {

        return $this->hasOne(CouponProductChannel::class, 'id', 'quote_id');

    }

    public function couponBrand()
    {
        return $this->hasOne(CouponBrand::class, 'id', 'brand_id')->append(['serv_type_name']);
    }


    public function payLog()
    {

        return $this->hasOne(PayLog::class, 'id', 'pay_log_id');

    }

    /**
     * @return \think\model\relation\HasOne
     */
    public function agentChannel()
    {
        return $this->hasOne(AgentChannel::class, 'id', 'cnid');
    }

    public function couponOrderSid()
    {
        return $this->hasOne(CouponOrderSid::class, 'id', 'sid');
    }

    /**
     * 订单状态
     * @param $value
     * @param $model
     * @return string
     */
    public function getOrderStatusTextAttr($value, $model)
    {
        return $this->return_status['name'] ?? '未知';
    }

    /**
     * 代理商名称
     * @param $value
     * @param $model
     * @return string
     */
    public function getAgentNameAttr($value, $model)
    {
        return !empty($this->agent) ? $this->agent->username : '未知';
    }

    /**
     * 代理商名称
     * @param $value
     * @param $model
     */
    public function getServTypeNameAttr($value, $model)
    {
        $nameArray = PRODUCT_SERV_TYPE[$this->serv_type] ?? [];

        return $nameArray['name'] ?? '未知';
    }

    /**
     * 结算状态名称
     * @param $value
     * @param $model
     */
    public function getSettleStatusNameAttr($value, $model)
    {
        $arr = [
            self::C_AGENT_SETTLE_STATUS_SUCCESS => '已结算',
            self::C_AGENT_SETTLE_STATUS_WAIT => '待结算',
            self::C_AGENT_SETTLE_STATUS_NO => '无结算',
        ];

//        $nameArray = PRODUCT_SERV_TYPE[$this->serv_type] ?? [];
        return $arr[$this->agent_settle_status] ?? '未知';
    }

    /**
     * 代理商公司名称
     * @param $value
     * @param $model
     * @return string
     */
    public function getAgentCompanyNameAttr($value, $model)
    {
        return !empty($this->agent) ? $this->agent->company_name : '未知';
    }

    /**
     * 小类型
     * @param $value
     * @param $model
     * @return void
     */
    public function getTypeNameAttr($value, $model) {
        $str = '普通订单';
        if ($model['type']) {
            $str = '自营订单';
        }
        return $str;
    }

    /**
     * 订单状态 h5
     * @param $value
     * @param $model
     * @return array
     */
    public function getReturnStatusAttr($value, $model)
    {

        (new OrderStatusService())->getStatus($this);

        if (!empty($this->params['return_status'])) {
            return $this->params['return_status'];
        }


        $returnMap = [
            1 => '待付款',
            2 => '充值中',
            3 => '充值成功',
            4 => '充值失败',
            5 => '退款中',
            6 => '退款成功',
            10 => '已取消',
            11 => '无效订单',
            12 => '已完成',
            13 => '已结算',
        ];
        $returnStatus = 1;
        $payStatus = $model['pay_status'];
        $status = $model['status'];
        $returnStatus = $model['refund_status'];
        $refundStatus = $model['refund_status'];
        $servType = $model['serv_type'] ?? '';
        if ($payStatus == self::C_PAY_STATUS_NO) {
            $returnStatus = 1;
        }
        return ['name' => $returnMap[$returnStatus], 'value' => $returnStatus];
    }


    /**
     * 有美生活、恋上梧桐，呆萌价配置的一些状态
     */
    public function getItemStatusAttr($value, $model)
    {

        $data = [
            1 => '已付款',
            2 => '已收货',
            3 => '已结算',
            4 => '已失效',
        ];

        $status = $this->return_status['value'] ?? 4;

        $strs = [
            3 => 1,//已支付 => 已付款
            12 => 2, //已完成 => 已收货
            13 => 3, //已结算 => 已结算
            4 => 4, //已退款 => 已失效
            11 => 4, //无效订单 => 已失效
            5 => 4, //退款中 => 已失效
            6 => 4, //已退款 => 已失效
        ];

        $dataValue = $strs[$status] ?? 4;

        return [
            'name' => $data[$dataValue] ?? '未知',
            'value' => $dataValue,
        ];
    }

    /**
     * 订单详情信息
     * @param $value
     * @param $model
     * @return array
     */
    public function getOrderDetailInfoAttr($value, $model) {
        $orderList = $model['ext_data'][JtkAroundService::ORDER_NOTIFY_SEND]['orderList'] ?? [];
        $temp = [];
        if ($orderList) {
            $orderUrl = [];
            foreach ($orderList as $item) {
                $url = $item['detailUrl'] ?? '';
                if ($url && !in_array($url, $orderUrl)) {
                    $orderUrl[] = $url;
                    $temp[] = $item;
                }
            }
        }
        return $temp;
    }

    /**
     * 退款状态
     * 退款注意事项：
     * 1、只有在商品未核销、且未过期才可申请退款。
     * 2、目前只能全额退，不支持部分退款。
     * @param $value
     * @param $model
     * @return array|string[]
     */
    public function getRefundBtnStatusAttr($value, $model) {
        $result = '';
        if ($model['type'] != self::TYPE_COUPON_SELF_EMPLOYED) {
            return $result;
        }
        if ($model['refund_status'] != self::C_REFUND_STATUS_NO) { // 未退款的才能退款
            return $result;
        }
        if ($model['pay_status'] == self::C_PAY_STATUS_NO) { // 已支付的订单才能退款
            return $result;
        }
        $jutuikeGoodsInfo = $model['ext_data'][JtkAroundService::JUTUIKE_GOODS_INFO] ?? [];
        if (empty($jutuikeGoodsInfo)) {
            return $result;
        }

        // 订单还没有发码回调，不能退款
        $orderNotifySend = $model['ext_data'][JtkAroundService::ORDER_NOTIFY_SEND] ?? [];
        if (empty($orderNotifySend)) {
            return $result;
        }

        if ($model['supplier_status'] == self::SUPPLIER_STATUS_REFUNDING) {
            $result = 'refunding'; // 退款中
            return $result;
        }
        // 退款只能申请一次
        $refundOrderRes = $model['ext_data'][JtkAroundService::ORDER_REFUND_ORDER_RES] ?? [];
        if ($refundOrderRes) {
            return $result;
        }

        // 退款只能申请一次，失败请联系客服
        $refundOrderResFail = $model['ext_data'][JtkAroundService::ORDER_REFUND_ORDER_RES_FAIL] ?? [];
        if ($refundOrderResFail) {
            return $result;
        }

        $orderNotifyCheck = $model['ext_data'][JtkAroundService::ORDER_NOTIFY_CHECK] ?? [];
        if ($orderNotifyCheck) { // 商品核销的不能在退款
            return $result;
        }
        if ($model['status'] == CouponOrder::C_STATUS_RECHARGE_SUCCESS
            && $model['supplier_status'] == CouponOrder::SUPPLIER_STATUS_SUCCESS) {
            return $result;
        }


        // 过期的商品不能在退款 validEndDate
        if (isset($jutuikeGoodsInfo['validEndDate']) && msectime() >= $jutuikeGoodsInfo['validEndDate']) {
            return $result;
        }
        $result = 'apply_refund'; // 申请退款
        return $result;
    }

    /**
     * 退款失败提示
     * @param $value
     * @param $model
     * @return mixed|string
     */
    public function getRefundFailTipAttr($value, $model) {
        $result = '';
        if ($model['type'] != self::TYPE_COUPON_SELF_EMPLOYED) {
            return $result;
        }

        $refundOrderResFail = $model['ext_data'][JtkAroundService::ORDER_REFUND_ORDER_RES_FAIL] ?? [];
        if (empty($refundOrderResFail)) {
            return $result;
        }

        if ($model['supplier_status'] == self::SUPPLIER_STATUS_REFUNDING) {
            return $result;
        }

//        $result = $refundOrderResFail['msg'] ?? '';
        $result = '提示: 退款失败,还需退款可联系客服';
        return $result;
    }


    /**
     * 代理平台返回字段
     * @param $servType
     * @return string[]
     */
    public static function agentPlatformField($servType = '')
    {
        $field = [

            'coupon_order.id', 'create_order_from', 'coupon_order.agent_id', 'cnid', 'order_id', 'product_name', 'amount', 'settle_price', 'profit', 'account', 'status', 'pay_time', 'pay_status', 'refund_status',
            'co.created_at', 'settled_at', 'complete_at', 'co.updated_at', 'serv_type', 'title', 'order_created_at', 'agent_settle_status', 'pay_type', 'supplier_order_sn', 'type', 'out_order_id,ac.name', 'product_image',
            'co.origin_amount', 'co.pay_amount', 'co.ext_data', 'co.supplier_status'
        ];
        if ($servType == PRODUCT_FOOD_SHOP_SERV) {
            $field[] = 'product_image';
        }
        return $field;
    }

    /**
     * 不同平台 参数处理
     * @param $params
     * @return array
     */
    public function couponOrderListPlatform($params)
    {
        $platform = $params['platform'] ?? '';
//        if ($platform == self::C_PLATFORM_AGENT && empty($params['agent_id'])) {
//            return ['status' => false, 'data' => '', 'msg' => '账号出错'];
//        }

        $field = [];

        if ($platform == self::C_PLATFORM_ADMIN) {
            $field = ['co.*', 'a.username as agent_username', 'a.company_name as agent_company_name', 'bs.name as supplier_name'];
        } elseif ($platform == self::C_PLATFORM_AGENT || Auth::from() == FROM_APP_API) {
            $servType = $params['serv_type'] ?? '';
            $field = self::agentPlatformField($servType);
        }

        if ($platform == 'app') {
            $field = ['co.*'];
        }

        $arr = [
            'field' => $field
        ];
        return $arr;
    }

    /**
     * h5订单列表
     * @param $params
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     */
    public function couponOrderListH5($params)
    {
        if (empty($params['user_id'])) {
            return fail('用户账号出错！');
        }
        $servType = $params['serv_type'] ?? PRODUCT_TRAVEL_OIL_SERV;
        $servType = explode(',', $servType);
        $field = [
            'id', 'order_id', 'product_name', 'out_order_id', 'supplier_order_sn', 'origin_amount', 'amount', 'pay_amount', 'status', 'pay_time', 'pay_status', 'refund_status',
            'created_at', 'product_image', 'serv_type', 'title', 'order_created_at', 'agent_settle_status'
        ];
        $query = CouponOrder::where([
//            'serv_type' => $servType,
            'user_id' => $params['user_id']
        ])
            ->whereIn('serv_type', $servType)
//            ->field($field)
            ->withSearch(['tab_status'], $params);

        $append = $this->getAppend();

        $query->append($append);

        $list = $query->order('created_at desc')->paginate()->toArray();

        return success('操作成功', $list);
    }

    /**
     * 订单列表
     * @param $params
     */
    public function couponOrderList($params)
    {
        $servType = $params['serv_type'] ?? '';
        $excelName = @PRODUCT_SERV_TYPE[$servType]['name'] ?? '' . '订单';

        $platform = $params['platform'] ?? '';
        $platformParamsArr = $this->couponOrderListPlatform($params);
        $query = CouponOrder::query()
            ->alias('co')
            ->when(!in_array(Auth::from(), ['admin', 'agent', 'api', 'phpunit']), function ($query) { //开放平台只显示已支付的
                /**@var Query $query */
                $query->where('co.pay_status', CouponOrder::C_PAY_STATUS_YES);
            })
            ->where('co.agent_id', '<>', 0) //代理不等于0
            ->field($platformParamsArr['field'])
            ->withSearch(self::$withSearch, $params);

        if ($platform == self::C_PLATFORM_ADMIN) {
            $query->join('agent a', 'a.id = coupon_order.agent_id', 'left')
                ->join('base_supplier bs', 'bs.id = co.supplier_id', 'left');
        }

        $auth = Auth::instance();
        if ($auth instanceof AuthApiService) {
            // H5处理的 以后放这里
            $query->where('co.user_id', Auth::id());

        }


        $query->join('agent_channel ac', 'ac.id = coupon_order.cnid', 'left');

        $with = (new Order())->getWith();
        array_push($with, 'agentChannel');

        $query->with($with);

        //开放平台--对外
        if (Auth::from() == FROM_OPEN_PLATFORM_API) {
            $query->hidden(['agent', 'agentChannel',]);

        }


        $append = $this->getAppend();

        $query->append($append);

        $order_date_type = $params['order_date_type'] ?? '';

        if ($order_date_type) {

            $query->order('co.' . $order_date_type . ' desc');

        } else {

            $query->order('co.id desc');

        }

        $isExport = $params['is_export'] ?? '';

        if (!empty($isExport)) {
            // 导出Excel表
            $data = $query->select()->toArray();
            $fieldArr = $this->downloadField($platform);
            return $this->downloadExcel($fieldArr, $data, $excelName);
        } else {
            $list = $query->paginate()->toArray();
            return ['status' => true, 'data' => $list];
        }

    }

    /**
     * 获取返回参数值
     * @return string[]
     */
    public function getAppend()
    {
        $append = ['order_status_text', 'openid', 'agent_name', 'type_name', 'agent_company_name', 'pay_type_name', 'open_order_sn', 'serv_type_name', 'settle_status_name'];//open_order_sn 第三方 取out_order_id 没有再取supplier_order_sn

        $auth = Auth::instance();


        //如果是有美生活
        if ($auth instanceof AuthYmshService || $auth instanceof AuthOpenService) {

            array_push($append, 'itemStatus');

        }

        array_push($append, 'return_status');

        //待支付过期时间
        if ($auth instanceof AuthApiService) {

            if ($this->status == self::C_STATUS_NO_SUBMIT) {
                array_push($append, 'expired_time');

            }

            if (input('serv_type') == PRODUCT_AROUND_SHOP_SERV) {

                array_push($append, 'orderDetailInfo');
                array_push($append, 'refundBtnStatus'); // 退款按钮状态
                array_push($append, 'refundFailTip'); // 退款失败提示
            }

        }



        //如果是开放平台
        if ($auth instanceof AuthOpenService) {

            array_push($append, 'user_share_openid');//分享者id
            array_push($append, 'detail_url');//订单详情页
        }


        return $append;
    }

    /**
     * 支付方式名称
     */
    public function getPayTypeNameAttr($value, $model)
    {
        $arr = [
            PAY_WEIXIN => '微信',
            PAY_ALIPAY => '支付宝',
        ];
        return $arr[$this->pay_type] ?? '未知';
    }

    /**
     * 第三方订单号
     */
    public function getOpenOrderSnAttr($value, $model)
    {
        if ($this->out_order_id) {
            return $this->out_order_id;
        }
        if ($this->supplier_order_sn) {
            return $this->supplier_order_sn;
        }

        return $this->order_id;
    }


    /**
     * 支付方式名称
     */
    public function getSupplierOrderSnAttr($value, $model)
    {

        $supplier_status = $model['supplier_status'] ?? '';
        $supplier_order_sn = $model['supplier_order_sn'] ?? '';
        $serv_type = $model['serv_type'];
        $type = $model['type'] ?? '';
        if ($serv_type == PRODUCT_COUPON_SERV && $type == self::TYPE_COUPON_SELF_EMPLOYED) {
            if ($supplier_status == self::SUPPLIER_STATUS_SUCCESS) { //支付了才有上游
                return $supplier_order_sn;
            } else {
                return '';
            }
        } else {
            return $supplier_order_sn;
        }

        return $supplier_order_sn;
    }

    /**
     * tab选项卡搜索
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchTabStatusAttr($query, $value, $params)
    {
//        $tabStatus = $params['tab_status'] ?? 'all';
        switch ($value) {
            case 'all': // 全部
                break;
            case 'wait_pay': // 待支付
                $query->where([
                    'coupon_order.pay_status' => self::C_PAY_STATUS_NO,
                    'coupon_order.agent_settle_status' => self::C_AGENT_SETTLE_STATUS_NO,
                    'coupon_order.status' => self::C_STATUS_NO_SUBMIT,
                ]);
                break;
            case 'pay': // 已支付
                $query->where([
                    'coupon_order.pay_status' => self::C_PAY_STATUS_YES,
                    'coupon_order.agent_settle_status' => self::C_AGENT_SETTLE_STATUS_NO
                ]);
                //权益的已支付 也有未提交状态
                $query->whereIn('coupon_order.status', [self::C_STATUS_PROCESSING, self::C_STATUS_NO_SUBMIT, self::C_STATUS_SUBMIT, self::C_STATUS_RECHARGE_SUCCESS]);

                break;
            case 'invalid':
                $query->where(function ($query) {
                    $query->where(
                        [
                            'co.status' => self::C_STATUS_RECHARGE_FAIL,
                            'co.refund_status' => self::C_REFUND_STATUS_NO,
                        ]
                    );
                    $query->whereOr(
                        [
                            'co.status' => self::C_STATUS_TIMEOUT_CLOSE,
                        ]
                    );
                });
                break;
            case 'finish':
                $query->where([
                    'coupon_order.status' => self::C_STATUS_RECHARGE_SUCCESS,
                    'coupon_order.pay_status' => self::C_PAY_STATUS_YES,
                    'coupon_order.agent_settle_status' => self::C_AGENT_SETTLE_STATUS_WAIT,
                ]);
                //$query->whereIn('coupon_order.agent_settle_status', [self::C_AGENT_SETTLE_STATUS_WAIT, self::C_AGENT_SETTLE_STATUS_SUCCESS]);
                break;
            case "refund":
                $query->whereIn('coupon_order.refund_status', [self::C_REFUND_STATUS_HAVE, self::C_REFUND_STATUS_ING]);
//                $query->whereIn('coupon_order.status', [self::C_STATUS_RECHARGE_FAIL]);
                break;
            case "settled"://已结算
                $query->where('coupon_order.agent_settle_status', self::C_AGENT_SETTLE_STATUS_SUCCESS);
                break;
            default:
                break;
        }
    }

    /**
     * 服务类型
     */
    public function searchServTypeAttr($query, $value, $params)
    {

        $table = !empty($this->table) ? $this->table . '.' : '';

        $serv_type = $params['serv_type'] ?? '';

        if (empty($serv_type)) return;

        $servType = explode(',', $serv_type);

        $query->whereIn($table . 'serv_type', $servType);

    }

    /**
     * 搜索标题
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchTitleAttr($query, $value, $params)
    {

        $path = request()->pathinfo();

        $search_type = $params['search_type'] ?? '';

        //我的推广不筛选title作为搜索条件，单独查询 品牌表或者商品表

        if ($path == 'stat.order/reportForm' && in_array($search_type,[CouponExtension::TYPE_CPS,CouponExtension::TYPE_PRODUCT,CouponExtension::TYPE_BRAND])) {

            return;

        }


        $table = !empty($this->table) ? $this->table . '.' : '';
        $title = $params['title'] ?? '';

        if (empty($title)) return;

        $query->whereLike($table . 'title', '%' . trim($title) . '%');

    }

    /**
     * 搜索标题
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchCnidAttr($query, $value, $params)
    {

        $table = !empty($this->table) ? $this->table . '.' : '';
        $cnid = $params['cnid'] ?? '';

        if (empty($cnid)) return;

        $query->where($table . 'cnid', $cnid);

    }

    /**
     * 搜索标题
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchProductIdAttr($query, $value, $params)
    {

        $table = !empty($this->table) ? $this->table . '.' : '';
        $product_id = $params['product_id'] ?? '';

        if (empty($product_id)) return;

        $from = input('from', '');
        if ($from == self::SEARCH_FROM) {
            $getChannelId = (new CouponExtension())->getChannelId();

            $query->where('coupon_order.cnid', $getChannelId);

        }

        $query->where($table . 'product_id', $product_id);

    }

    /**
     * 充值账号
     * @param $value
     * @param $model
     * @return string
     */
    public function searchAccountAttr($query, $value, $params)
    {
        $table = !empty($this->table) ? $this->table . '.' : '';

        $account = $params['account'] ?? '';

        if (empty($account)) return;

        $query->whereLike($table . 'account', '%' . trim($account) . '%');
    }

    /**
     * 服务类型
     */
    public function searchTemplateIdAttr($query, $value, $params)
    {

        $table = !empty($this->table) ? $this->table . '.' : '';

        $template_id = $params['template_id'] ?? '';

        if (empty($template_id)) return;

        $query->where($table . 'template_id', $template_id);

    }

    /**
     * 服务类型
     */
    public function searchCreateOrderFromAttr($query, $value, $params)
    {

        $table = !empty($this->table) ? $this->table . '.' : '';

        $create_order_from = $params['create_order_from'] ?? '';

        if (empty($create_order_from)) return;

        $query->where($table . 'create_order_from', $create_order_from);

    }

    /**
     * 财务管理 的结算状态  和 agent_settle_status 有一些差别
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchFinanceStatusAttr($query, $value, $params)
    {
        $table = !empty($this->table) ? $this->table . '.' : '';

        $finance_status = $params['finance_status'] ?? '';

        if (empty($finance_status)) return;

        if ($finance_status == 'all') {
            $query->estimate();
        }
        if ($finance_status == 'settle') {
            $query->where($table . 'agent_settle_status', self::C_AGENT_SETTLE_STATUS_SUCCESS);
        }
        if ($finance_status == 'wait_settle') {
            $query->estimate()->where($table . 'agent_settle_status', '<>', CouponOrder::C_AGENT_SETTLE_STATUS_SUCCESS);
        }

    }

    /**
     * 类型
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchSettleTypeAttr($query, $value, $params)
    {

        $settle_type = $params['settle_type'] ?? '';

        if (!empty($settle_type)) {
            $query->where('coupon_order.settle_type', $settle_type);
        }
    }

    /**
     * 搜索开始时间
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchStartAtAttr($query, $value, $params)
    {


        $start_at = $params['start_at'] ?? '';

        if (empty($start_at)) return;

        $order_date_type = $params['order_date_type'] ?? 'updated_at';

        do {
            //月
            $valid = Carbon::hasFormat($start_at, 'Y-m');

            if ($valid) {
                $start_at = Carbon::parse($start_at)->format('Y-m-d');
                break;
            }

        } while (false);

        //日
        /** @var Query $query */

        $query->where('coupon_order.' . $order_date_type, '>=', $start_at);

    }


    /**
     * 搜索开始时间
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchAgentIdAttr($query, $value, $params)
    {

        $agent_id = $params['agent_id'] ?? '';

        if (empty($agent_id)) return;

        /** @var Query $query */

        $query->where('coupon_order.agent_id', $agent_id);

    }

    /**
     * 搜索开始时间
     * @param $query
     * @param $value
     * @param $params
     */
//    public function searchChannelNameAttrOld($query, $value, $params)
//    {
//
//        $channel_name = $params['channel_name'] ?? '';
//
//        if (empty($channel_name)) return;
//
//
//        /** @var Query $query */
//
//        $query->where('ac.name', '=', trim($channel_name));
//
//    }

    /**
     * 搜索开始时间
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchChannelNameAttr($query, $value, $params)
    {

        $table = !empty($this->table) ? $this->table . '.' : '';

        $channel_name = $params['channel_name'] ?? '';

        if (empty($channel_name)) return;


        /** @var Query $query */

        $query->where($table . 'cnid', 'in', function ($sql) use ($channel_name) {
            $sql->name('agent_channel')->field('id')
                ->where('name', $channel_name);
        });

    }


    /**
     * 搜索开始时间
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchEndAtAttr($query, $value, $params)
    {
        $end_at = $params['end_at'] ?? '';

        if (empty($end_at)) return;

        $order_date_type = $params['order_date_type'] ?? 'updated_at';


        do {
            $valid = Carbon::hasFormat($end_at, 'Y-m');

            if ($valid) {
                $end_at = Carbon::parse($end_at)->endOfMonth()->format('Y-m-d H:i:s');
                break;
            }

            $end_at = Carbon::parse($end_at)->endOfDay()->format('Y-m-d H:i:s');
        } while (false);

        /** @var Query $query */

        $query->where('coupon_order.' . $order_date_type, '<=', $end_at);
    }


    /**
     * 搜索支付时间
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchPayTimeAttr($query, $value, $params)
    {
        $pay_time = $params['pay_time'] ?? '';
        if (!$pay_time) return;
        /** @var Query $query */
        $query->whereBetweenTime('pay_time', Carbon::parse($pay_time[0])->startOfDay()->format('Y-m-d H:i:s'), Carbon::parse($pay_time[1])->endOfDay()->format('Y-m-d H:i:s'));
    }

    public function searchChannelIdAttr($query, $value, $params)
    {
        $channel_id = $params['channel_id'] ?? '';
        if (!$channel_id) return;

        $query->where('coupon_order.cnid', $channel_id);
    }

    public function searchProductNameAttr($query, $value, $params)
    {
        $product_name = $params['product_name'] ?? '';
        if (!$product_name) return;

        $query->where('product_name', 'like', '%' . $product_name . '%');
    }

    /**
     * 搜索供应商
     */
    public function searchSupplierNameAttr($query, $value, $params)
    {
        $supplier_name = $params['supplier_name'] ?? '';

        if (!empty($supplier_name)) {

            $query->where('bs.name', 'like', "%$supplier_name%");

        }
    }

    /**
     * 搜索栏
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchBarFieldAttr($query, $value, $params)
    {
        // 商品名称
        $productName = $params['product_name'] ?? '';
        $query->when($productName, function ($subQuery) use ($productName) {
            $subQuery->where('product_name', 'like', '%' . $productName . '%');
        });

        // 订单ID
//        $orderId = $params['order_id'] ?? '';
//        $query->when($orderId, function ($subQuery) use ($orderId) {
//            $subQuery->where(function ($query)use($orderId){
//                $query->where('order_id', 'like', '%' . $orderId . '%');
//            });
//        });

        // 代理商名称
//        $agentName = $params['agent_name'] ?? '';
//        $query->when($agentName, function ($subQuery) use ($agentName) {
//            $subQuery->where('company_name', 'like', '%' . $agentName . '%');
//        });
    }


    /**
     * 下单时间 搜索
     * @param $query
     * @param $value
     * @param $data
     */
    public function searchCreatedDateAttr($query, $value, $data)
    {
        if ($value) {
            $query->whereBetweenTime('coupon_order.order_created_at', $value[0], $value[1] . ' 23:59:59');
        }
    }


    /**
     * 完成时间 搜索
     * @param $query
     * @param $value
     * @param $data
     */
    public function searchCompleteAtAttr($query, $value, $data)
    {
        if ($value) {
            $query->whereBetweenTime('coupon_order.complete_at', $value[0], $value[1] . ' 23:59:59');
        }
    }


    public function searchSearchTypeAttr($query, $value, $data)
    {

        if (!$value) {
            return;
        }
        if (!in_array($value, [StatService::SEARCH_TYPE_BRAND, StatService::SEARCH_TYPE_COUPONP_RODUCT_CHANNEL, StatService::SEARCH_TYPE_CPS])) {
            return;
        }


        /**@var AgentChannel $channel ** */
        $channel = AgentChannel::query()
            ->where('channel_type', AgentChannel::CHANNEL_TYPE_BRAND_EXTENSION)
            ->where('agent_id', Auth::agentId())
            ->find();
        if (!$channel) {
            $query->where('coupon_order.cnid', -1);
            return;
        }

        //统计系统默认的渠道
        $query->where('coupon_order.cnid', $channel->id);

        $cpsIds = CouponBrand::query()
            ->where('belong', CouponBrand::BELONG_JUTUIKE)
//            ->where('status',CouponBrand::STATUS_ACTIVE)
            ->column('id');

        switch ($value) {
            case StatService::SEARCH_TYPE_CPS:
                $query->whereIn('coupon_order.brand_id', $cpsIds);
                break;

            case StatService::SEARCH_TYPE_BRAND:
                $query->where('coupon_order.extension_type',CouponExtension::TYPE_BRAND);
                $query->where('coupon_order.type', CouponOrder::TYPE_COUPON_SELF_EMPLOYED);
                $query->whereNotIn('coupon_order.brand_id', $cpsIds);
                break;

            case StatService::SEARCH_TYPE_COUPONP_RODUCT_CHANNEL:
                $query->where('coupon_order.extension_type',CouponExtension::TYPE_PRODUCT);
                $query->where('coupon_order.type', CouponOrder::TYPE_COUPON_SELF_EMPLOYED);
                break;
        }


    }

    /**
     * 列表搜索来源
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchFromAttr($query, $value, $params)
    {

        $from = $params['from'] ?? '';
        $brand_id = $params['brand_id'] ?? '';
        $product_id = $params['product_id'] ?? '';
        $table = !empty($this->table) ? $this->table . '.' : '';

        if ($from != self::SEARCH_FROM) return;


        if (!empty($brand_id)) {

            $couponBrand = CouponBrand::query()->where('id',$brand_id)->find();
            if (empty($couponBrand)) return;
            if ($couponBrand->belong == CouponBrand::BELONG_JUTUIKE){
                return;
            }

            $query->where($table . 'extension_type', CouponExtension::TYPE_BRAND);
            return;

        }
        if (!empty($product_id)){

            $query->where($table . 'extension_type', CouponExtension::TYPE_PRODUCT);
            return;
        }


    }


    /**
     * 搜索品牌id
     */
    public function searchBrandIdAttr($query, $value, $data)
    {
        if (!$value) {
            return false;
        }
        $from = input('from', '');
        if ($from == self::SEARCH_FROM) {
            $getChannelId = (new CouponExtension())->getChannelId();

            $query->where('coupon_order.cnid', $getChannelId);

        }

        $query->where('coupon_order.brand_id', $value);
    }


    /**
     * Excel表字段
     * @param $servType
     * @return array
     */
    protected function downloadField($platform, $servType = '')
    {
        // code 不同产品有不同字段 后续可用 $servType
        $fieldArr = [];
        if ($platform == self::C_PLATFORM_ADMIN) {
            $fieldArr = [
                '系统订单号' => 'order_id',
                '供应商订单号' => 'supplier_order_sn',
                '接口订单号' => 'out_order_id',
                '商品名称' => 'product_name',
                '销售价' => 'amount',
                '结算价' => 'settle_price',
                '成本价' => 'supplier_price',
                '平台利润' => 'platform_profit',
                '代理商利润' => 'profit',
                '充值号码' => 'account',
                '订单状态' => 'order_status_text',
                '下单时间' => 'order_created_at',
                '支付时间' => 'pay_time',
                '完成时间' => 'complete_at',
                '代理商名称' => 'agent_username',
                '代理商公司名称' => 'agent_company_name',
                '供应商' => 'supplier_name',
                '支付方式' => 'pay_type_name',
                '渠道' => 'agentChannel.name',
                '订单类型' => 'serv_type_name',
                '结算状态' => 'settle_status_name',

//                '应用' => 'app_name',
//                '商户' => 'merchant_name',
            ];
        } elseif ($platform == self::C_PLATFORM_AGENT) {
            $fieldArr = [
                '系统订单号' => 'order_id',
                '商品名称' => 'product_name',
                '销售价' => 'amount',
                '结算价' => 'settle_price',
                '代理商利润' => 'profit',
                '充值号码' => 'account',
                '订单状态' => 'order_status_text',
                '下单时间' => 'order_created_at',
                '支付时间' => 'pay_time',
                '完成时间' => 'complete_at',
                '渠道' => 'agentChannel.name',
                '订单类型' => 'serv_type_name',
                '结算状态' => 'settle_status_name',
            ];
        }
        return $fieldArr;
    }

    /**
     * excel列表导出
     * @param $fieldArr
     * @param $data
     * @param $excelName
     */
    public function downloadExcel($fieldArr, $data, $excelName = '')
    {
        // 需要加\t 字段处理
        $fieldAddT = [
            'order_id', 'supplier_order_sn', 'out_order_id'
        ];

        // 单位 分转成元 字段处理
        $fieldPriceUnit = [
            'amount',
            'settle_price',
            'supplier_price',
            'profit',
            'platform_profit',
            'pay_amount',
            'no_settle',
            'already_settle_amount',
        ];

        // 数据和导出字段名一一对应
        $res = [];
        foreach ($data as $item) {
            $temp = [];
            foreach ($fieldArr as $name => $field) {
                do {
                    if (strstr($field, '.')) {
                        $ex = explode('.', $field);
                        if (count($ex) != 2) {
                            break;
                        }
                        if (empty($item[$ex[0]][$ex[1]])) {
                            break;
                        }
                        $value = $item[$ex[0]][$ex[1]];
                        break;
                    }
                    $value = $item[$field] ?? '';
                    if (in_array($field, $fieldAddT)) {
                        $value = $value ? $value . "\t" : '';
                    } elseif (in_array($field, $fieldPriceUnit)) {
                        $value = $value ? fen2yuan($value) : '';
                    } /*elseif ($field == 'agent_username') {
                        $value = $item['agent']['username'] ?? '';
                    }*/
                } while (false);

                $temp[] = $value;
            }
            $res[] = $temp;
        }
        $export = new Export;
        return $export->downloadExcel(array_keys($fieldArr), $res, $excelName);
    }


    /**
     * 预估收入 ，所有的
     * @param $query
     */
    public function scopeEstimate($query)
    {
        /**
         * @var \think\db\Query $query
         */
        $table = !empty($this->table) ? $this->table . '.' : '';
        $query->whereIn($table . 'status', [
            CouponOrder::C_STATUS_RECHARGE_SUCCESS,
            CouponOrder::C_STATUS_PROCESSING,
            CouponOrder::C_STATUS_SUBMIT,
            CouponOrder::C_STATUS_NO_SUBMIT,
        ])
            ->where($table . 'refund_status', CouponOrder::C_REFUND_STATUS_NO) //没退款
            ->where($table . 'agent_id', '<>', 0)
            ->where($table . 'pay_status', CouponOrder::C_PAY_STATUS_YES);
//            ->where('agent_settle_status', '<>', CouponOrder::C_AGENT_SETTLE_STATUS_SUCCESS);

    }


    /**
     * 待结算的是扣除已结算的  扣除已结算的预估
     * @param $query
     */
    public function scopeExceptSettleEstimate($query)
    {
        /**
         * @var \think\db\Query $query
         */
//        $table = !empty($this->table) ? $this->table . '.' : '';
        $query->whereIn('status', [
            CouponOrder::C_STATUS_RECHARGE_SUCCESS,
            CouponOrder::C_STATUS_PROCESSING,
            CouponOrder::C_STATUS_SUBMIT,
            CouponOrder::C_STATUS_NO_SUBMIT,
        ])
            ->where('refund_status', CouponOrder::C_REFUND_STATUS_NO) //没退款

            ->where('pay_status', CouponOrder::C_PAY_STATUS_YES)
            ->where('agent_settle_status', '<>', CouponOrder::C_AGENT_SETTLE_STATUS_SUCCESS);

    }


}